/**
 * COPYRIGHT. whx. ALL RIGHTS RESERVED.
 * Project: just-core
 * Author: whx <harrywu304@gmail.com>
 * Create On: Dec 2, 2011 7:21:23 PM
 */

package org.justframework.util;

import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * IP referred utility
 */
public class IPUtil {

	/**
	 * local ip list
	 */
	private static List<InetAddress> localAddressList;

	/**
	 * 取得本机网络地址列表
	 * 
	 * @return
	 */
	public static List<InetAddress> getLocalAddresses() {
		if (localAddressList == null) {
			localAddressList = new ArrayList<InetAddress>();
			try {
				// 获取可用的网络接口
				Enumeration<NetworkInterface> interfaces = NetworkInterface
						.getNetworkInterfaces();
				while (interfaces != null && interfaces.hasMoreElements()) {
					NetworkInterface interfaceN = interfaces.nextElement();
					// 获取网络接口上的网络地址
					Enumeration<InetAddress> ienum = interfaceN
							.getInetAddresses();
					while (ienum.hasMoreElements()) {
						InetAddress ia = ienum.nextElement();
						// 添加网络地址到本机网络地址列表
						localAddressList.add(ia);
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return localAddressList;
	}

	/**
	 * 取得本机IP（多网卡主机，默认取外网IP，如果外网IP也有多个，取获取到的第一个）
	 * 
	 * @return 本机IP
	 */
	public static String getLocalIP() {
		return getLocalIP(false);
	}

	/**
	 * 取得本机IP地址 
	 * 
	 * @param isInter
	 *            是否返回内网IP
	 * @return 本机ip地址
	 */
	public static String getLocalIP(boolean isInter) {
		// 初始化本地地址列表
		if (localAddressList == null) {
			localAddressList = getLocalAddresses();
		}
		String localIP = "";
		for (InetAddress ia : localAddressList) {
			String ip = ia.getHostAddress();
			// 忽略ipv6地址和loopback地址
			if (ia instanceof Inet6Address || ip.startsWith("127")) {
				continue;
			}
			// 记录找到的第一个ipv4地址
			if (StringUtil.isNullOrBlank(localIP)) {
				localIP = ip;
			}
			if (isInter && isReservedIP(ip)) {
				return ip;
			}
			if (!isInter && !isReservedIP(ip)) {
				return ip;
			}
		}
		return localIP;
	}

	/**
	 * check if ip is reserved ip
	 * 
	 * @param address
	 * @return
	 */
	private static boolean isReservedIP(String address) {
		boolean ret = false;
		if (address.startsWith("10.") || address.startsWith("192.168.")) {
			ret = true;
		} else if (address.startsWith("172.")) {
			String[] sections = address.split("\\.");
			if (sections.length == 4) {
				int set = Integer.parseInt(sections[1]);
				if (set >= 16 && set <= 31) {
					ret = true;
				}
			}
		}
		return ret;
	}

}
